### funo mtcor
## se os pacotes necesrios para a funo no esto instalados,  necessrio instal-los usando
if(!require(reshape2))install.packages("reshape2")
if(!require(ggplot2))install.packages("ggplot2")

mtcor <- function(Data, fun = "cor", sig = 0.05){
  # carrega os pacotes necessrios
  library(reshape2)
  library(ggplot2)
  
  ## avalia se existem mais de duas colunas no banco de dados
  if(ncol(Data)<2) stop('less than 2 columns in Data')
  
  ## avalia se os argumentos inseridos en fun so caracteres
  if(class(fun) != "character") stop('fun must be class character')
  
  ## Seleciona colunas numricas ou com caracteres dependendo o valor de fun
  if(fun == "cor"){
    indx <- sapply(Data, is.integer);
    Data[indx] <- lapply(Data[indx], function(x) as.numeric(x));
    Data <- Filter(is.numeric, bd);
  } else if(fun == "chisq"){
    indx <- sapply(Data, is.factor);
    Data[indx] <- lapply(Data[indx], function(x) as.character(x));
    Data <- Filter(is.character, Data);
  }
  
  ## avalia se existem mais de duas colunas no banco de dados
  if(ncol(Data)<2) stop('less than 2 columns in Data');
  
  ## cria matriz vazia
  cor_mat <- matrix(nrow = ncol(Data), ncol = ncol(Data));
  
  ## substitui nomes das colunas e linhas da matriz
  colnames(cor_mat) <- colnames(Data);
  rownames(cor_mat) <- colnames(Data);
  
  ## preenche as informacoes da matriz com os valores de cada comparao
  ## os valores de i e j correspondem aos nomes das colunas do banco
  for(i in colnames(Data)){
    ## seleciona a coluna do banco correspondente ao valor de i
    c1 <- Data[,i]
    for(j in colnames(Data)){
    ## seleciona a coluna do banco correspondente ao valor de j
    c2 <- Data[,j]
    
    if(fun == "cor"){
      ## comparao das duas variveis usando o teste de correlao de pearson
      c3<-cor(c1, c2)
    } else if(fun == "chisq"){
      ## comparao das duas variveis usando a correlao qui quadrada de pearson
      c3<- round(chisq.test(c1, c2)$p.value, 10)
    }
    ## substitui os valores da matriz na posicao i e j com o valor de c3 
    cor_mat[i, j] <- c3
    }
  }
  
  ## define como NA as comparaes entre uma mesma coluna
  diag(cor_mat) <- NA
  
  ## faz um resumo das comparaes testadas
  if(fun == "cor"){
    positivas <- length(cor_mat[cor_mat > 0 & is.na(cor_mat) == F])/2
    negativas <- length(cor_mat[cor_mat < 0 & is.na(cor_mat) == F])/2
    summary_cor <- paste("There are", positivas, "positives correlations and",
                         negativas, "negatives correlations", sep = " ")
  } else if(fun == "chisq"){
    sig_05 <- length(cor_mat[cor_mat < sig & is.na(cor_mat) == F])/2
    n_sig_05 <- length(cor_mat[cor_mat > sig & is.na(cor_mat) == F])/2
    summary_cor <- paste("There are", sig_05, "associations with p value < 0.05 and",
                         n_sig_05, "associations with  p value > 0.05", sep = " ")
  }
  
  ## muda a estrutura da matriz num data.frame de 3 colunas
  graph_cor <- reshape2::melt(cor_mat, na.rm = TRUE)
  
  ## plota as comparae em um grfico base
  graph_cor <- ggplot(data = graph_cor, aes(Var2, Var1, fill = value))+
    geom_tile(color = "white")+
    theme_minimal()+ 
    theme(axis.text.x = element_text(angle = 45, vjust = 1, 
                                     size = 12, hjust = 1))+
    coord_fixed()+
    theme(
      axis.title.x = element_blank(),
      axis.title.y = element_blank())
    
  ## define uma escala de cor no grfico dependendo o valor de fun
  if(fun == "cor"){
    graph_cor <- graph_cor +
    scale_fill_gradient2(low = "blue", high = "red", mid = "white", 
                         midpoint = 0, limit = c(-1,1), space = "Lab", 
                         name="Pearson\nCorrelation") 
  } else if(fun == "chisq"){
    graph_cor <- graph_cor +
      scale_fill_gradient(low = "red", high = "blue", limit = c(0,1),
                          space = "Lab", 
                           name="P value\nPearson\nChi-squared") 
  }
  
  ## mostra o resumo das comparaes
  print(summary_cor)
  
  ## retorna o grfico como resultado final
  return(graph_cor)
}

# ### bancos de dados do pacote dataset
# data("airquality")
# bd <- data.frame(airquality, stringsAsFactors = F)
# str(bd)
# mtcor(Data = bd, fun = "cor")
# 
# data("HairEyeColor")
# bd <- data.frame(HairEyeColor, stringsAsFactors = F)
# str(bd)
# mtcor(Data = bd, fun = "chisq")
